package com.bestv.bsr.core.service.impl.ah.fallback;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.bestv.bsr.core.aspect.WebLogAspect;
import com.bestv.bsr.core.constants.CacheConstants;
import com.bestv.bsr.core.service.impl.ah.dto.AHRequestParam;
import com.bestv.bsr.core.service.impl.ah.dto.AHZYWLResponseDto;
import com.bestv.bsr.core.service.impl.ah.remote.AHRemoteService;
import com.bestv.remote.context.MethodContext;
import com.bestv.remote.context.ParamContext;
import com.bestv.remote.context.ServerContext;
import com.bestv.remote.interfaces.BlockHandler;
import com.bestv.remote.interfaces.FallbackHandler;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

import java.util.Map;


/**
 * 安徽移动 失败处理
 *
 * @author taojiacheng
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class AHFallbackHandler implements BlockHandler<AHZYWLResponseDto>, FallbackHandler<AHZYWLResponseDto> {

    private final RedissonClient redissonClient;
    private final AHRemoteService ahRemoteService;

    @Override
    public AHZYWLResponseDto handlerBlock(ServerContext serverContext, MethodContext methodContext, ParamContext paramContext, BlockException blockException) {
        log.info("-----推荐id:{},安徽第三方推荐接口<已经熔断>进入请求容错机制接口-----", MDC.get(WebLogAspect.TRACE_ID));
        return fallback(paramContext);
    }

    @Override
    public AHZYWLResponseDto handlerFallback(ServerContext serverContext, MethodContext methodContext, ParamContext paramContext, Throwable throwable) {
        log.info("-----推荐id:{},安徽第三方推荐接口<发生降级>进入请求容错机制接口-----", MDC.get(WebLogAspect.TRACE_ID));
        return fallback(paramContext);
    }

    private AHZYWLResponseDto fallback(ParamContext paramContext) {
        Map<String, Object> requestParams = paramContext.getRequestParams();
        AHRequestParam param = (AHRequestParam) requestParams.get("requestParam");
        RBucket<AHZYWLResponseDto> bucket = redissonClient.getBucket(String.format(CacheConstants.AH_DEFAULT, param.getChannel(), param.getCatename()));
        AHZYWLResponseDto ahZywlResponseDto = bucket.get();
        if (ahZywlResponseDto != null) {
            return ahZywlResponseDto;
        }
        // 缓存中没有数据调用接口
        AHZYWLResponseDto fallbackResp = ahRemoteService.fallback(param);
        if (fallbackResp != null) {
            bucket.set(fallbackResp);
        }
        return fallbackResp;
    }

}
